home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Palettes / TabMatrixPalette1.5 / UITabActionCell.subproj / UITabActionCell.m < prev   
Text File  |  1995-06-12  |  9KB  |  348 lines

  1. /* UITabActionCell.m 
  2.  *
  3.  * By Bill Edney, Sean Hill, Mark Onyschuk, and Art Isbell
  4.  *
  5.  */
  6.  
  7. #import "UITabActionCell.h"
  8.  
  9. #import <appkit/appkit.h>
  10.  
  11. #import <objc/List.h>
  12.  
  13. #import "drawTab.h"    // pswrap that draws tab ends.
  14.  
  15. @implementation UITabActionCell
  16.  
  17.  
  18. // Methods Overridden From the Superclass
  19. - initTextCell:(const char *)aString
  20. // Initializes a new instance of the receiver.
  21. {
  22.     [super initTextCell:aString];
  23.  
  24.  // finish the initialization process 
  25.     [self finishInitializing];
  26.  
  27.     return self;
  28. }
  29.  
  30. - awake
  31. // Performs additional intialization of the receiver after reading
  32. // from an NXTypedStream.
  33. {
  34.  // do the superclass' awake method 
  35.     [super awake];
  36.  
  37.  // finish the initializing process 
  38.     [self finishInitializing];
  39.  
  40.     return self;
  41. }
  42.  
  43. - setFont:fontObj
  44. // Sets the receiver's font to <fontObj> and fetches font info used
  45. // during the receiver's display.
  46. {
  47.     NXCoord    lineHeight;
  48.  
  49.  // Do the superclass' init method 
  50.     [super setFont:fontObj];
  51.  
  52.  // Grab the font information for the contents of the cell 
  53.     NXTextFontInfo(fontObj, &ascender, &descender, &lineHeight);
  54.  
  55.  // Set tabHeight to match that in EOF IB's StackView.  This results in a
  56.  // height of 17 for Helvetica 12.
  57.     tabHeight = lineHeight - descender + 5.0;
  58.  
  59.  // Set tabBezierImageWidth to provide reasonable scaling behavior.
  60.     tabBezierImageWidth = tabHeight * 14.0 / 17.0;
  61.  
  62.     return self;
  63. }
  64.  
  65. - drawInside:(const NXRect *)cellFrame inView:controlView
  66. // Draws the receiver inside <cellFrame> in view <controlView>.
  67. {
  68.     NXCoord    halfImageWidth = tabBezierImageWidth / 2.0;
  69.     NXPoint    leftImageOrigin,
  70.             rightImageOrigin;
  71.     
  72.     float    unselectedGray;
  73.     
  74.     NXRect     textFrame,
  75.             lowerBezelFrame;
  76.         
  77.     List    *controlCellList;
  78.     int        indx,
  79.             intImageWidth = (int)(tabBezierImageWidth + 0.5);
  80.  
  81.  // if there are no contents, then punt... 
  82.     if (!contents) {
  83.     return self;
  84.     }
  85.  
  86.     if([Window defaultDepthLimit]<=NX_TwoBitGrayDepth)
  87.         unselectedGray = NX_DKGRAY;
  88.     else
  89.         unselectedGray = 0.5;
  90.  
  91.  
  92.  // if <controlView> is not a kind of Matrix (i.e. in IB)
  93.     if (![controlView isKindOf:[Matrix class]]) {
  94.         [super drawInside:cellFrame inView:controlView];    
  95.         return self;
  96.     }
  97.  
  98.  // set drawing to opaque
  99.     PSsetalpha(1.0);
  100.  
  101.     PSsetgray([controlView backgroundGray]);
  102.     NXRectFill(cellFrame);
  103.  
  104.  // fetch information about ourselves in our Matrix
  105.     controlCellList = [controlView cellList];
  106.     indx = [controlCellList indexOf:self];
  107.         
  108.  
  109.  // set up the lowerBezelFrame that will be used for drawing the bezel
  110.  // at our bottom
  111.     NXSetRect(&lowerBezelFrame,
  112.           NX_X(cellFrame) + halfImageWidth,
  113.           NX_MAXY(cellFrame) - 1.0,
  114.           NX_WIDTH(cellFrame), 1.0);
  115.  
  116.  // set textFrame to cellFrame 
  117.     textFrame = *cellFrame;
  118.  
  119.  // set up the leftImageOrigin 
  120.     leftImageOrigin.x = NX_X(cellFrame);
  121.     leftImageOrigin.y = NX_MAXY(cellFrame);
  122.  
  123.  // if indx is 0 (we are the first cell) 
  124.     if (indx == 0) {
  125.     // if we are selected 
  126.     if ([self isSelected]) {
  127.     // Draw selected left tab bezier at leftImageOrigin.
  128.         drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  129.             intImageWidth, (int)tabHeight, NX_WHITE, NX_LTGRAY);
  130.     } else {
  131.     // Otherwise, draw left tab bezier at leftImageOrigin.
  132.         drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  133.             intImageWidth, (int)tabHeight, NX_LTGRAY,
  134.         unselectedGray);
  135.  
  136.     // subtract a half tabBezierImageWidth from lowerBezelFrame's x 
  137.         lowerBezelFrame.origin.x -= halfImageWidth;
  138.     }
  139.  
  140.     // add a tabBezierImageWidth to textFrame's x 
  141.     textFrame.origin.x += tabBezierImageWidth;
  142.  
  143.      // subtract a tabBezierImageWidth plus half tabBezierImageWidth minus 1.0
  144.      // from textFrame's width
  145.     textFrame.size.width -= tabBezierImageWidth + halfImageWidth - 1.0;
  146.     } else {
  147.     // subtract a half tabBezierImageWidth from leftImageOrigin's x 
  148.     leftImageOrigin.x -= halfImageWidth;
  149.  
  150.     // if the cell to left of us is selected 
  151.     if ([[controlCellList objectAt:indx - 1] isSelected]) {
  152.     // Draw left tab bezier at leftImageOrigin.
  153.         drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  154.             intImageWidth, (int)tabHeight, NX_LTGRAY,
  155.         unselectedGray);
  156.  
  157.     // Draw selected right tab bezier at leftImageOrigin.
  158.         drawRightTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  159.             intImageWidth, (int)tabHeight, NX_BLACK, NX_LTGRAY);
  160.     } else if ([self isSelected]) {
  161.     // otherwise, if we are selected 
  162.  
  163.     // Draw right tab bezier at leftImageOrigin.
  164.     // composite tabEndImage to leftImageOrigin 
  165.         drawRightTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  166.             intImageWidth, (int)tabHeight, NX_BLACK, unselectedGray);
  167.  
  168.     // Draw selected left tab bezier at leftImageOrigin.
  169.         drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  170.             intImageWidth, (int)tabHeight, NX_WHITE, NX_LTGRAY);
  171.     } else {
  172.     // Draw left tab bezier at leftImageOrigin.
  173.         drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  174.             intImageWidth, (int)tabHeight, NX_LTGRAY,
  175.         unselectedGray);
  176.  
  177.     // Draw right tab bezier at leftImageOrigin.
  178.         drawRightTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y,
  179.             intImageWidth, (int)tabHeight, NX_BLACK, unselectedGray);
  180.  
  181.     // subtract a half tabBezierImageWidth from lowerBezelFrame's x 
  182.         lowerBezelFrame.origin.x -= tabBezierImageWidth;
  183.  
  184.     // add 1.0 to lowerBezelFrame's width 
  185.         lowerBezelFrame.size.width += 1.0;
  186.     }
  187.  
  188.     // add a half tabBezierImageWidth to textFrame's x 
  189.     textFrame.origin.x += halfImageWidth;
  190.  
  191.     // subtract a tabBezierImageWidth minus 1.0 from textFrame's width 
  192.     textFrame.size.width -= tabBezierImageWidth - 1.0;
  193.     }
  194.  
  195.  // if indx is less than controlCellList's count minus 1 then we're
  196.  // not the last cell, and...
  197.     if (indx < [controlCellList count] - 1) {
  198.     // draw the cell to the right of us 
  199.     [controlView drawCell:[controlCellList objectAt:indx + 1]];
  200.     } else {
  201.     // set up the rightImageOrigin 
  202.     rightImageOrigin.x = NX_X(cellFrame) + NX_WIDTH(cellFrame)
  203.       - tabBezierImageWidth;
  204.     rightImageOrigin.y = NX_Y(cellFrame) + NX_HEIGHT(cellFrame);
  205.  
  206.     // if we are selected 
  207.     if ([self isSelected]) {
  208.     // Draw selected right tab bezier at rightImageOrigin.
  209.         drawRightTabBezier((int)rightImageOrigin.x,
  210.             (int)rightImageOrigin.y, intImageWidth,
  211.         (int)tabHeight, NX_BLACK, NX_LTGRAY);
  212.     } else {
  213.     // Draw right tab bezier at rightImageOrigin.
  214.         drawRightTabBezier((int)rightImageOrigin.x,
  215.             (int)rightImageOrigin.y, intImageWidth,
  216.         (int)tabHeight, NX_BLACK, unselectedGray);
  217.     }
  218.  
  219.     // subtract a tabBezierImageWidth from textFrame's width 
  220.     textFrame.size.width -= halfImageWidth;
  221.  
  222.     // add a half tabBezierImageWidth to lowerBezelFrame's width 
  223.     lowerBezelFrame.size.width += halfImageWidth;
  224.     }
  225.  
  226.  // erase the cell 
  227.  
  228.  // if we are selected 
  229.     if ([self isSelected]) {
  230.     // set our drawing color to NX_LTGRAY 
  231.     PSsetgray(NX_LTGRAY);
  232.     } else {
  233.     PSsetgray(unselectedGray);
  234.     }
  235.     
  236.     textFrame.size.height = tabHeight;
  237.     textFrame.origin.y = NX_MAXY(cellFrame) - tabHeight;
  238.  
  239.  // fill in textFrame 
  240.     NXRectFill(&textFrame);
  241.  
  242.  // now draw the upper bezel 
  243.  
  244.  // set our drawing color to NX_LTGRAY 
  245.  // if we are selected 
  246.     if ([self isSelected]) {
  247.     // set our drawing color to NX_LTGRAY 
  248.     PSsetgray(NX_WHITE);
  249.     } else {
  250.     PSsetgray(NX_LTGRAY);
  251.     }
  252.  
  253.  // set textFrame's height to 1.0 
  254.     textFrame.size.height = 1.0;
  255.  
  256.  // fill in textFrame 
  257.     NXRectFill(&textFrame);
  258.  
  259.  // now draw the text 
  260.  
  261.     // If we are enabled, draw NX_BLACK, else draw NX_LTGRAY
  262.     if ([self isEnabled])
  263.         PSsetgray(NX_BLACK);
  264.     else
  265.     PSsetgray(NX_LTGRAY);
  266.  
  267.  // draw the cell's contents 
  268.  
  269.     if (NXDrawingStatus == NX_DRAWING && [[self font] screenFont])
  270.     [[[self font] screenFont] set];
  271.     else
  272.     [[self font] set];
  273.  
  274.     // The offsets were empirically set by emulating the StackView used in the
  275.     // EOF IB's File Window.
  276.     PSmoveto(NX_X(&textFrame) + 3.0, NX_Y(&textFrame) + tabHeight - 4.0);
  277.     PSshow(contents);
  278.  
  279.  // if we are not selected 
  280.     if (![self isSelected]) {
  281.     // draw the lower bezel 
  282.  
  283.     // set our drawing color to NX_WHITE 
  284.     PSsetgray(NX_WHITE);
  285.  
  286.     // fill in lowerBezelFrame 
  287.     NXRectFill(&lowerBezelFrame);
  288.     }
  289.     return self;
  290. }
  291.  
  292. - highlight:(const NXRect *)cellFrame inView:aView lit:(BOOL)flag
  293. {
  294.     [super highlight:cellFrame inView:aView lit:flag];
  295.     [self drawInside:cellFrame inView:aView];
  296.     return self;
  297. }
  298.  
  299. - calcCellSize:(NXSize *)theSize inRect:(const NXRect *)aRect
  300. {
  301.     theSize->height = tabHeight;
  302.     theSize->width =  (2*tabBezierImageWidth+
  303.                     [[self font] getWidthOf:[self stringValue]]);
  304.     return self;
  305. }
  306.  
  307. - (BOOL)trackMouse:(NXEvent *)theEvent
  308.             inRect:(const NXRect *)cellFrame
  309.             ofView:controlView
  310. {
  311.     BOOL    boolValue = [super trackMouse:(NXEvent *)theEvent
  312.                                     inRect:(const NXRect *)cellFrame
  313.                                     ofView:controlView];
  314.  
  315.     if (theEvent->type == NX_MOUSEUP)
  316.     {
  317.         [self incrementState];
  318.     }
  319.     
  320.     return boolValue;
  321. }
  322.  
  323. - (BOOL)startTrackingAt:(const NXPoint *)startPoint inView:aView
  324. {
  325.     [aView sendAction];
  326.     return NO;
  327. }
  328.  
  329. // Other Instance Methods 
  330. - finishInitializing
  331. {
  332.  // all text displayed will be in Helvetica, 12 point 
  333.     //[self setFont:[Font newFont:"Helvetica" size:12.0]];
  334.     [self setFont:[self font]];
  335.  
  336.  // send the action on no event; we'll handle sending the event ourselves
  337.      [self sendActionOn:NX_NULLEVENTMASK];
  338.  
  339.     return self;
  340. }
  341.  
  342. // Accessor Methods
  343.  
  344. - (BOOL)isSelected
  345. {
  346.     return (cFlags1.highlighted || cFlags1.state);
  347. }
  348. @end